package com.inspur.dgov.vlbod.helper;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.inspur.dgov.vlbod.entity.LiveBroadcast;
import com.inspur.dgov.vlbod.helper.model.*;
import com.inspur.dgov.vlbod.util.Secures;
import com.xylink.config.SDKConfigMgr;
import com.xylink.log.XyLinkLogType;
import com.xylink.sdk.SdkMethodV2;
import com.xylink.util.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.sql.Timestamp;
import java.util.*;

/**
 * XyVideoHelper
 * xie_yh
 * package com.inspur.dgov.vlbod.helper
 * 小鱼视频对接
 *
 * @author xie_yh
 * @date 2023/5/23 10:56
 */
@Slf4j
@Component
public class XyVideoHelper {

    @Value("${dgov.xyvideo.server.url}")
    private String xyApiUrl;

    @Value("${dgov.xyvideo.clientId}")
    private String xyClientId;

    @Value("${dgov.xyvideo.enterpriseID}")
    private String xyEnterpriseId;

    @Value("${dgov.xyvideo.clientSecret}")
    private String xyClientSecret;

    @Value("${dgov.xyvideo.api.createMeeting}")
    private String apiCreateMeeting;

    @Value("${dgov.xyvideo.api.subscribeLive}")
    private String subscribeLive;

    @Value("${dgov.xyvideo.api.updateLive}")
    private String updateLive;

    @Value("${dgov.xyvideo.api.meetingInfo}")
    private String meetingInfo;

    @Value("${dgov.xyvideo.api.deleteLive}")
    private String deleteLive;

    @PostConstruct
    public void init() {
        SDKConfigMgr.initSDKConfig(xyApiUrl, xyClientId, xyClientSecret, xyEnterpriseId);
        SDKConfigMgr.setXyLinkLogType(XyLinkLogType.LogBack);
    }

    private void printApiTime(String api,long enterTime){
        long duration = System.currentTimeMillis() - enterTime;
        log.info("api调用时间 -{}-时间{}毫秒",api,duration);
    }

    /**
     * 创建会议室
     * @param data
     * @return
     */
    public XyMeetingRoom createMeetingRoom(LiveBroadcast data) {
        long enterTime = System.currentTimeMillis();
        try {
            String uri = apiCreateMeeting + xyEnterpriseId;
            XyMettingRoomPO mettingRoomPO = new XyMettingRoomPO();
            mettingRoomPO.setMeetingName(data.getTitle());
            mettingRoomPO.setStartTime(Timestamp.valueOf(data.getStartTime()).getTime());
            mettingRoomPO.setEndTime(Timestamp.valueOf(data.getEndTime()).getTime());
            // 密码SM2解密
            if(StrUtil.isNotBlank(data.getMeetingPassword())){
                mettingRoomPO.setPassword(Secures.sm2Decrypt(data.getMeetingPassword()));
            }
            // 增加控制密码
            if(StrUtil.isNotBlank(data.getControlPassword())){
                mettingRoomPO.setControlPassword(Secures.sm2Decrypt(data.getControlPassword()));
            }
            mettingRoomPO.setRequirePassword(false);
            Map<String, Object> configs = new HashMap<>();
            configs.put("mediaEncrypt", "AUTO");
            configs.put("autoRecord", StrUtil.equals(data.getAutoRecording(), "1"));
            mettingRoomPO.setConfigs(configs);

            Result<XyMeetingRoom> result = SdkMethodV2.sdkPost(uri, mettingRoomPO, XyMeetingRoom.class);

            if (!result.isSuccess()) {
                log.error("create meeting room failed!{},{},{}", data.getTitle(),
                        result.getErrorStatus(),
                        result.getErrorMsg());
                return null;
            }
            printApiTime("创建会议室",enterTime);
            return result.getData();
        } catch (Throwable t) {
            log.error("create meeting room error:", t);
            return null;
        }
    }

    /**
     * 修改会议室
     * @param data
     * @return
     */
    public boolean updateMeetingRoom(LiveBroadcast data) {
        long enterTime = System.currentTimeMillis();
        try {
            String uri = "/api/rest/external/v1/meetingInfo/" + data.getMeetingRoomNumber() + "?enterpriseId=" + xyEnterpriseId;
            Map<String,Object> mettingRoomMap = new HashMap<>();
            mettingRoomMap.put("meettingRoomName",data.getTitle());
            mettingRoomMap.put("expireTime",Timestamp.valueOf(data.getEndTime()).getTime());
            // 密码SM2解密
            if(StrUtil.isNotBlank(data.getMeetingPassword())){
                mettingRoomMap.put("password",Secures.sm2Decrypt(data.getMeetingPassword()));
            }
            mettingRoomMap.put("autoRecord", StrUtil.equals(data.getAutoRecording(), "1"));

            Result<Map> result = SdkMethodV2.sdkPut(uri, mettingRoomMap, Map.class);

            if (!result.isSuccess()) {
                log.error("update meeting room failed!{},{},{}", data.getTitle(),
                        result.getErrorStatus(),
                        result.getErrorMsg());
                return false;
            }
            printApiTime("修改会议室",enterTime);
            return true;
        } catch (Throwable t) {
            log.error("update meeting room error:", t);
            return false;
        }
    }

    /**
     * 创建直播
     * @param data
     * @return
     */
    public XyLiveVideo createLiveBroadcast(LiveBroadcast data) {
        long enterTime = System.currentTimeMillis();
        try {
            String uri = subscribeLive + xyEnterpriseId + "&meetingRoomNumber=" + data.getMeetingRoomNumber();
            XyLiveVideoPO liveVideoPO = new XyLiveVideoPO();
            liveVideoPO.setTitle(data.getTitle());
            // 密码SM2解密
            if(StrUtil.isNotBlank(data.getMeetingPassword())){
                liveVideoPO.setPassword(Secures.sm2Decrypt(data.getMeetingPassword()));
            }
            liveVideoPO.setStartTime(Timestamp.valueOf(data.getStartTime()).getTime());
            liveVideoPO.setEndTime(Timestamp.valueOf(data.getEndTime()).getTime());
            liveVideoPO.setDetail(data.getBriefIntroduction());
            liveVideoPO.setLocation(data.getLocation());
            liveVideoPO.setNemoNumber(data.getNemoNumber());
            liveVideoPO.setAutoRecording(StrUtil.equals(data.getAutoRecording(), "1"));
            liveVideoPO.setAutoPublishRecording(StrUtil.equals(data.getAutoPublishRecording(), "1"));
            liveVideoPO.setDefaultLiveResolutionType(data.getDefaultResolution());
            liveVideoPO.setExtras(data.getExtrasConfig());

            Result<XyLiveVideo> result =  SdkMethodV2.sdkPost(uri, liveVideoPO, XyLiveVideo.class);

            if (!result.isSuccess()) {
                log.error("create live broadcast failed!{},{},{}", data.getTitle(),
                        result.getErrorStatus(),
                        result.getErrorMsg());
                return null;
            }
            printApiTime("创建直播",enterTime);
            return result.getData();
        } catch (Throwable t) {
            log.error("create live broadcast error:", t);
            return null;
        }
    }

    /**
     * 更新直播
     * @param data
     * @return
     */
    public XyLiveVideo updateLiveBroadcast(LiveBroadcast data) {
        long enterTime = System.currentTimeMillis();
        try {
            String uri = updateLive + xyEnterpriseId + "&meetingRoomNumber=" + data.getMeetingRoomNumber() + "&liveId=" + data.getLiveId();
            XyLiveVideoPO liveVideoPO = new XyLiveVideoPO();
            liveVideoPO.setTitle(data.getTitle());
            // 密码SM2解密
            if(StrUtil.isNotBlank(data.getMeetingPassword())){
                liveVideoPO.setPassword(Secures.sm2Decrypt(data.getMeetingPassword()));
            }
            liveVideoPO.setStartTime(Timestamp.valueOf(data.getStartTime()).getTime());
            liveVideoPO.setEndTime(Timestamp.valueOf(data.getEndTime()).getTime());
            liveVideoPO.setDetail(data.getBriefIntroduction());
            liveVideoPO.setLocation(data.getLocation());
            liveVideoPO.setNemoNumber(data.getNemoNumber());
            liveVideoPO.setAutoRecording(StrUtil.equals(data.getAutoRecording(), "1"));
            liveVideoPO.setAutoPublishRecording(StrUtil.equals(data.getAutoPublishRecording(), "1"));
            liveVideoPO.setDefaultLiveResolutionType(data.getDefaultResolution());
            liveVideoPO.setExtras(data.getExtrasConfig());

            Result<XyLiveVideo> result =  SdkMethodV2.sdkPost(uri, liveVideoPO, XyLiveVideo.class);

            if (!result.isSuccess()) {
                log.error("create live broadcast failed!{},{},{}", data.getTitle(),
                        result.getErrorStatus(),
                        result.getErrorMsg());
                return null;
            }
            printApiTime("更新直播",enterTime);
            return result.getData();
        } catch (Throwable t) {
            log.error("update live broadcast error:", t);
            return null;
        }
    }

    /**
     * 删除直播
     * @param data
     * @return
     */
    public boolean deleteLiveBroadcast(LiveBroadcast data) {
        String confPwd = null;
        if(StrUtil.isNotBlank(data.getMeetingPassword())){
            Secures.sm2Decrypt(data.getMeetingPassword());
        }
        String uri = deleteLive + xyEnterpriseId + "/conf/" + data.getMeetingRoomNumber() + "/live/" + data.getLiveId() + "?confPwd=" + confPwd + "&enterpriseId=" + xyEnterpriseId;
        try {
            Result<Map> result = SdkMethodV2.sdkDelete(uri, Map.class);
            if (!result.isSuccess()) {
                log.error("delete live broadcast failed {},{},{}",
                        data.getTitle(), result.getErrorStatus(), result.getErrorMsg());
                return false;
            }
        } catch (Throwable t) {
            log.error("delete live broadcast failed", t);
            return false;
        }
        return true;
    }

    /**
     * 删除会议室
     * @param meetingRoomNumber
     * @return
     */
    public boolean deleteMeetingRoom(String meetingRoomNumber) {
        String uri = meetingInfo + meetingRoomNumber + "?enterpriseId=" + xyEnterpriseId;
        try {
            Result<Map> result = SdkMethodV2.sdkDelete(uri, Map.class);
            if (!result.isSuccess()) {
                log.error("delete meeting room failed {},{},{}",
                        meetingRoomNumber, result.getErrorStatus(), result.getErrorMsg());
                return false;
            }
        } catch (Throwable t) {
            log.error("delete meeting room failed", t);
            return false;
        }
        return true;
    }

    public String getLiveVideoStatus(String liveId,String confNo,String confPassword){
        long enterTime = System.currentTimeMillis();
        StringBuilder uri = new StringBuilder("/api/rest/external/v1/liveVideo5/query");
        uri.append("?enterpriseId=").append(xyEnterpriseId);
        uri.append("&liveId=").append(liveId);
        uri.append("&meetingRoomNumber=").append(confNo);
        if (StrUtil.isNotBlank(confPassword)) {
            uri.append("&password=").append(Secures.sm2Decrypt(confPassword));
        }
        try {
            Result<Map> result = SdkMethodV2.sdkGet(uri.toString(), Map.class);
            if (!result.isSuccess()) {
                log.error("start live status failed!{},{},{},{}", confNo, liveId,
                        result.getErrorStatus(),
                        result.getErrorMsg());
                return null;
            }
            printApiTime("获取直播状态",enterTime);
            return (String) result.getData().get("status");
        } catch (Throwable t) {
            log.error("start live status failed", t);
            return null;
        }
    }

    public boolean setLiveVideStatus(String liveId, String status, String confNo, String confPassword) {
        long enterTime = System.currentTimeMillis();
        StringBuilder uri = new StringBuilder("/api/rest/external/v1/liveVideo3/enterprise/");
        uri.append(xyEnterpriseId);
        uri.append("/conf/").append(confNo);
        uri.append("/live/").append(liveId);
        uri.append("/status?");
        if (StrUtil.isNotBlank(confPassword)) {
            uri.append("confPwd=").append(Secures.sm2Decrypt(confPassword));
        }
        uri.append("&enterpriseId=").append(xyEnterpriseId);
        Map<String, Object> paramBodyMap = new HashMap<>();
        paramBodyMap.put("status", status);
        try {
            Result<Map> result = SdkMethodV2.sdkPut(uri.toString(), paramBodyMap, Map.class);
            if (!result.isSuccess()) {
                log.error("start live status failed!{},{},{},{}", confNo, status,
                        result.getErrorStatus(),
                        result.getErrorMsg());
                return false;
            }
            printApiTime("设置直播状态",enterTime);
            return true;
        } catch (Throwable t) {
            log.error("start live status failed", t);
            return false;
        }
    }

    public List<Map> selectLiveVideoList(String liveId, String meetingRoomNumber) {
        long enterTime = System.currentTimeMillis();
        String uri = "/api/rest/external/v1/liveVideo3/enterprise/liveVideoList?enterpriseId=" + xyEnterpriseId;
        try {
            Map<String, Object> map = new HashMap<>();
            map.put("liveId", liveId);
            map.put("confNo", meetingRoomNumber);
            List<Map<String, Object>> paramBodyList = new ArrayList<>();
            paramBodyList.add(map);
            Result<List> result = SdkMethodV2.sdkPut(uri, paramBodyList, List.class);

            printApiTime("获取回放视频列表",enterTime);
            if (!result.isSuccess()) {
                log.error("select live video failed {},{},{},{}",
                        liveId, meetingRoomNumber, result.getErrorStatus(), result.getErrorMsg());
            } else {
                if (result.getData().size() > 0) {
                    return result.getData();
                }
                log.error("result live video list is null {},{}", liveId, meetingRoomNumber);
            }
            return null;
        } catch (Exception t) {
            log.error("select live video list failed {}", t.getMessage());
            return null;
        }
    }

    public String getThumbnailUrl(String meetingRoomNumber){
        long enterTime = System.currentTimeMillis();
        String uri = "/api/rest/external/v1/meetingroom/vods/page?enterpriseId=" + xyEnterpriseId;
        try {
            Map<String, Object> paramBodyMap = new HashMap<>();
            paramBodyMap.put("meetingRoomNumbers", Arrays.asList(meetingRoomNumber));
            Result<Map> result = SdkMethodV2.sdkPut(uri, paramBodyMap, Map.class);

            printApiTime("获取回放视频列表",enterTime);
            if (!result.isSuccess()) {
                log.error("get live video thumbnail url failed {},{},{}",
                         meetingRoomNumber, result.getErrorStatus(), result.getErrorMsg());
                return null;
            } else {
                List<Map<String,Object>> list = (List<Map<String, Object>>) result.getData().get("list");
                if (list.size() <= 0) {
                    return null;
                }
                return MapUtil.getStr(list.get(0),"thumbnailUrl");
            }
        } catch (Exception t) {
            log.error("get live video thumbnail url failed {}", t.getMessage());
            return null;
        }
    }

}
